package SimulationEngine;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

import org.jhotdraw.draw.DefaultDrawing;
import org.jhotdraw.draw.Drawing;
import org.junit.Test;

import stateDiagram.SimulationEngine;
import stateDiagram.figures.EndStateFigure;
import stateDiagram.figures.StartStateFigure;
import stateDiagram.figures.StateFigure;
import stateDiagram.figures.TransitionFigure;
import junit.framework.TestCase;

public class SimulationEngineTest extends TestCase {
   
	private DefaultDrawing drawing;
	private StartStateFigure start;
   private EndStateFigure end;
   private StateFigure s1;
   private StateFigure s2;
   private TransitionFigure t1;
   private TransitionFigure t2;
   private TransitionFigure t3;
   private TransitionFigure t4;
   private TransitionFigure t5;
   private final String a1 = "Dance";
   private final String a2 = "Mambo";
   private final String a3 = "Tango";
   private final String a4 = "Waltz";
   private final String a5 = "Flamenco";
   private final String e1 = "MoveFromStart";
   private final String e2 = "MoveFromS1";
   private final String e3 = "MoveFromS2";
   private final String e4 = "RepeatS2";
   private final String e5 = "Finish";
   private URI input; //I hate working with URIs so much
   private String expectedOutput;
   
   //start connects to s1 via t1
   //s1 connects to s2 via t2
   //s2 connects to s1 via t3
   //s2 connects to s2 via t4
   //s1 connects to end via t5
   
   //runs before each test
  public void setup(){
	  
    start = new StartStateFigure();
    end = new EndStateFigure();
    s1 = new StateFigure();
    s2 = new StateFigure();
    
    s1.setName("s1");
    s1.setEntry("s1entry");
    s1.setExit("s1exit");
    
    s2.setName("s2");
    s2.setEntry("s2entry");
    s2.setExit("s2exit");
    
    t1 = new TransitionFigure();
    t2 = new TransitionFigure();
    t3 = new TransitionFigure();
    t4 = new TransitionFigure();
    t5 = new TransitionFigure();
    
    t1.getTransitionEntity().setFromState(start.getStateEntity());
    t1.getTransitionEntity().setToState(s1.getStateEntity());
    t1.getTransitionEntity().setAction(a1);
    t1.getTransitionEntity().setName(e1);
    
    t2.getTransitionEntity().setFromState(s1.getStateEntity());
    t2.getTransitionEntity().setToState(s2.getStateEntity());
    t2.getTransitionEntity().setAction(a2);
    t2.getTransitionEntity().setName(e2);
    
    t3.getTransitionEntity().setFromState(s2.getStateEntity());
    t3.getTransitionEntity().setToState(s1.getStateEntity());
    t3.getTransitionEntity().setAction(a3);
    t3.getTransitionEntity().setName(e3);
    
    t4.getTransitionEntity().setFromState(s2.getStateEntity());
    t4.getTransitionEntity().setToState(s2.getStateEntity());
    t4.getTransitionEntity().setAction(a4);
    t4.getTransitionEntity().setName(e4);
    
    t5.getTransitionEntity().setFromState(s1.getStateEntity());
    t5.getTransitionEntity().setToState(end.getStateEntity());
    t5.getTransitionEntity().setAction(a5);
    t5.getTransitionEntity().setName(e5);
    
    start.getStateEntity().addOutgoingTransition(t1.getTransitionEntity());
    
    s1.addDependency(t2);
    s1.getStateEntity().addOutgoingTransition(t2.getTransitionEntity());
    s1.addDependency(t5);
    s1.getStateEntity().addOutgoingTransition(t5.getTransitionEntity());
    
    s2.addDependency(t3);
    s2.getStateEntity().addOutgoingTransition(t3.getTransitionEntity());
    s2.addDependency(t4);
    s2.getStateEntity().addOutgoingTransition(t4.getTransitionEntity());
    
    drawing = new DefaultDrawing();
    
    drawing.add(start);
    drawing.add(end);
    drawing.add(s1);
    drawing.add(s2);
    drawing.add(t1);
    drawing.add(t2);
    drawing.add(t3);
    drawing.add(t4);
    drawing.add(t5);
    
    try {
		input = new URI("file:/C:/simdebug.txt");
	} catch (URISyntaxException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
    
    setupURIs();
  }
  
  private void setupURIs(){
	try {
		FileWriter fw = new FileWriter(input.getPath());
		BufferedWriter writer = new BufferedWriter(fw);
	    
	    writer.write(e1 + "\n");
	    writer.write(e2 + "\n");
	    writer.write(e2 + "\n");  //Impossible instruction
	    writer.write(e4 + "\n");
	    writer.write(e3 + "\n");
	    writer.write(e2 + "\n");
	    writer.write(e3 + "\n");
	    writer.write("Do the Truffle Shuffle\n"); //Nonexistant instruction
	    writer.write(e5);
	    
	    writer.close();
	    fw.close();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
    
    //write the expected output
	expectedOutput = new String();
	expectedOutput.concat("Line 1: " + a1 + " \n");
	expectedOutput.concat("Line 2: " + a2 + " \n");
	expectedOutput.concat("Line 3: Event '" + e2 + "' not applicable to current state, staying at " + s2.getStateEntity().getName() + ". \n");
	expectedOutput.concat("Line 4: " + a4 + " \n");
	expectedOutput.concat("Line 5: " + a3 + " \n");
	expectedOutput.concat("Line 6: " + a2 + " \n");
	expectedOutput.concat("Line 7: " + a3 + " \n");
	expectedOutput.concat("Line 8: Event 'Do the Truffle Shuffle' not applicable to current state, staying at " + s1.getStateEntity().getName() + ". \n");
	expectedOutput.concat("Line 9: " + a5 + " \n");
	expectedOutput.concat("Simulation complete.\n");
	expectedOutput.concat("Simulation ended in state " + end.getStateEntity().getName());
  }
  
  //Test if our simulation runs right.
  @Test
  public void testSimulation(){
	  setup();
	  String s = new String();
	  SimulationEngine sim = new SimulationEngine();
	  sim.simulate(drawing, input);
	  assertEquals(s,expectedOutput);
	 
  }
}
